package miage.ecom.Main;
import java.io.*;
import java.util.Properties;
import java.util.TreeMap;
import javax.naming.Context;
import javax.naming.InitialContext;
import miage.ecom.commandes.ShellCommand;
import miage.ecom.Shell.ShellContext;
import miage.ecom.Shell.ShellContextImpl;
import miage.ecom.commandes.*;
import miage.sessions.ecom.remote.EcomAdminRemote;
import miage.sessions.ecom.remote.EcomCustomerRemote;




    public class Shell implements Runnable{
        
    private static TreeMap _commandNameMap = new TreeMap();
    private static ShellContext _context = new ShellContextImpl(_commandNameMap) {};
    private boolean stop = false;
    protected static InputStream in;
    protected static PrintStream out;
    protected static PrintStream err;
    public final static String PROMPT="PROMPT";
    public final static String BANNER="BANNER";
    public final static String ADMIN="ADMIN";
    public final static String LANGUAGE="LANGUAGE";
    public final static String CURRENCY="CURRENCY";
    public final static String OUTPUT="OUTPUT";
    public static int accountId;
    private static String serverName="localhost";
   
    
    
    public Shell(String args[],boolean isAdmin){
    //////////////////
    //initialisation//
    //////////////////
    out=System.out;
    err=System.err;
    in=System.in;
    if(!parseArgs(args))
    stop();
    ////////////////
    //init context//
    ////////////////
    ShellContext context=getContext();
    context.setVar(PROMPT,"->");
    context.setVar(BANNER,getBanner());
    context.setVar(ADMIN,isAdmin);
    context.setVar(LANGUAGE, "fr");
    context.setVar(CURRENCY, "EUR");
    context.setVar(OUTPUT, "TEXT");
    connect(serverName,context);
    initContextCommands(context);
    }
    /**
    * rĂŠcupĂ¨re les arguments et remplit les variables accountId et serverName
    * @param args
    * @return
    */
    protected static boolean parseArgs(String args[]){
    try{
    if(args.length<1){
    return false;
    }else{
    accountId=Integer.parseInt(args[0]);
    if(args.length>1){
    serverName=args[1];
    }
    return true;
    }
    }catch(Exception ex){
    err.println("accountId non indiquĂŠ");
    return false;
    }
    }
    protected final ShellContext getContext() {
    return _context;
    }
    /**
    * place le cursor d'arrĂŞt Ă  true
    */
    protected final void stop(){
        
    stop = true;
    }
    /**
    * lance le Shell
    */
    @Override
    public final void run(){
        
    String banner;	
    String line;
    BufferedReader br=null;
    if(stop) {
    banner=(String)_context.getVar(BANNER);
    if(banner!=null) out.println(banner);
    line = null;
    br = new BufferedReader(new InputStreamReader(in));
    }
    while (stop)
    {
    String prompt;
    prompt=(String)_context.getVar(PROMPT);
    if(prompt==null) prompt=">";
    out.print(prompt);
    
    
    try {
    line = br.readLine();
    
    
    } catch (IOException ex) {
    err.println("Could not read input, please try again.");
    continue;
    }
    line = line.trim();
    if (line.length() == 0)
    {
    continue;
    }
    try {
    executeCommand(line, out, err);
    } catch (Exception ex) {
    err.println("Shell: " + ex.getMessage());
    }
    }
    }
    private String getBanner(){
    StringBuilder sb=new StringBuilder();	
    sb.append("\n------------------------------------------------------------------------");
    sb.append("\n\t\t| ECOM application |");
    sb.append("\n| Ouissem Bekada - Virginie Messe - Romain Sanny - Maxime Vizcaino |");
    sb.append("\n------------------------------------------------------------------------");
    return sb.toString();
    }
    /**
    * supprime une commande de la liste
    * @param name
    */
    protected final synchronized void removeCommand(String name)
    {
    out.println("Removing command : " + name);
    _commandNameMap.remove(name);
    }
    /**
    * execute la commande demandĂŠ par l'utilisateur
    * @param commandLine
    * @param out
    * @param err
    * @throws Exception
    */
    protected final synchronized void executeCommand(String commandLine, PrintStream out, PrintStream err) throws Exception
    {
    commandLine = commandLine.trim();
    String commandName = (commandLine.indexOf(' ') >= 0)
    ? commandLine.substring(0, commandLine.indexOf(' ')) : commandLine;
    ShellCommand command = getCommand(commandName);
    if (command != null)
    {
        command.getShortDescription();
    command.execute(commandLine, out, err);
    }
    else
    {
    err.println("Command not found.");
    }
    }
    protected final synchronized ShellCommand getCommand(String name)
    {
    ShellCommand sc = (ShellCommand) _commandNameMap.get(name);
    return sc;
    }
    /**
    * ajoute une commande Ă  la liste
    * @param sc
    */
    protected static synchronized void addCommand(ShellCommand sc)
    {
    _commandNameMap.put(sc.getName(), sc);
    }
    /**
    * vide la liste de commandes
    */
    protected static synchronized void clearCommands()
    {
    _commandNameMap.clear();
    }
    /**
    * se connecte aux EJB
    * @param serverName
    * @param context
    */
    private void connect(String serverName,ShellContext context) {
    try {
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
    props.setProperty("org.omg.CORBA.ORBInitialHost", serverName);
    props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
    InitialContext initialContext = new InitialContext(props);
    
    EcomCustomerRemote ecomCustomer = (EcomCustomerRemote) initialContext.lookup("java:global/ecomProject-ejb/EcomCustomer");
    context.setVar("customerEJB", ecomCustomer);
    
    if((Boolean)context.getVar(ADMIN)){
    EcomAdminRemote ecomAdmin = (EcomAdminRemote) initialContext.lookup("java:global/ecomProject-ejb/EcomAdmin");
    context.setVar("adminEJB", ecomAdmin);
    
    }
    } catch (Exception ex) {
    err.println(ex.getMessage());
    System.exit(0);
    }
    }
    /**
    * initialise la liste de commande en ajoutant seulement les commandes souhaitĂŠes
    * @param context
    */
    private static void initContextCommands(ShellContext context){
    clearCommands();
    // Add "context" command.
    addCommand(new VarCommandImpl(context));
    // Add "echo" command.
    addCommand(new EchoCommandImpl(context));
    // Add "help" command.
    addCommand(new HelpCommandImpl(context));
    // Add "account" command.
  //  addCommand(new AccountCommandImpl(context));
    // Add "cart" command.
     addCommand(new CartCommandImpl(context));
    // Add "currency" command.
   // addCommand(new CurrencyCommandImpl(context));
    // Add "language" command.
    addCommand(new LanguageCommandImpl(context));
    // Add "output" command.
    addCommand(new OutputCommandImpl(context));
    // Add "product" command.
    addCommand(new ProductCommand(context));
    
    // Add "store" command.
   // addCommand(new StoreCommandImpl(context));
    // Add "quit" command.
    addCommand(new SimpleQuitCommandImpl(context));
    }
    /**
    * modifie le langage et initialise les commandes
    * @param language
    */
    public static void setLanguage(String language){
    _context.setVar(LANGUAGE, language);
    initContextCommands(_context);
    }
    /**
    * modifie la monnaie
    * @param currency
    */
    public static void setCurrency(String currency){
    _context.setVar(CURRENCY, currency);
    }
    /**
    * modifie le type de sortie
    * @param output
    */
    public static void setOutput(String output){
    _context.setVar(OUTPUT, output);
    }
    }

